package com.slicktechnologies.server;

import static com.googlecode.objectify.ObjectifyService.ofy;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.appengine.api.datastore.ReadPolicy.Consistency;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.cmd.Query;
import com.simplesoftwares.client.library.ReturnFromServer;
import com.simplesoftwares.client.library.appstructure.SuperModel;
import com.simplesoftwares.client.library.appstructure.search.MyQuerry;
import com.simplesoftwares.client.library.libservice.GenricService;
import com.slicktechnologies.shared.Contract;
import com.slicktechnologies.shared.Quotation;
import com.slicktechnologies.shared.ServiceType;
import com.slicktechnologies.shared.common.businessprocesslayer.Customer;
import com.slicktechnologies.shared.common.businessprocesslayer.Expense;
import com.slicktechnologies.shared.common.businessunitlayer.Branch;
import com.slicktechnologies.shared.common.businessunitlayer.Company;
import com.slicktechnologies.shared.common.helperlayer.Config;
import com.slicktechnologies.shared.common.helperlayer.LoggedIn;
import com.slicktechnologies.shared.common.helperlayer.User;
import com.slicktechnologies.shared.common.personlayer.Employee;
import com.slicktechnologies.shared.common.productlayer.Category;
import com.slicktechnologies.shared.common.productlayer.ItemProduct;
import com.slicktechnologies.shared.common.productlayer.ServiceProduct;
import com.slicktechnologies.shared.common.productlayer.SuperProduct;
import com.slicktechnologies.shared.common.relationalLayer.BranchRelation;
import com.slicktechnologies.shared.common.relationalLayer.CustomerRelation;
import com.slicktechnologies.shared.common.relationalLayer.EmployeeRelation;
import com.slicktechnologies.shared.common.relationalLayer.VendorRelation;




// TODO: Auto-generated Javadoc
/**
 * The Class GenricServiceImpl.
 */
@SuppressWarnings("serial")
public class GenricServiceImpl extends RemoteServiceServlet implements
GenricService {
static{
	
	
	try{
		
	  
	  
		 ObjectifyService.register(ServiceType.class);
		 ObjectifyService.register(LoggedIn.class);
		 ObjectifyService.register(ServiceType.class);
		
		
		  ObjectifyService.register(Quotation.class);
		 
		  ObjectifyService.register(Contract.class);
	  ObjectifyService.register(Config.class);
	  ObjectifyService.register(Company.class);
	 
	  
	  ObjectifyService.register(Branch.class);
	  ObjectifyService.register(BranchRelation.class);
	  ObjectifyService.register(Employee.class);
	 
	  ObjectifyService.register(EmployeeRelation.class);
	  ObjectifyService.register(User.class);
	  ObjectifyService.register(ItemProduct.class);
	  ObjectifyService.register(SuperProduct.class);
	  ObjectifyService.register(ServiceProduct.class);
	
	  ObjectifyService.register(Expense.class);
	  
	  ObjectifyService.register(Customer.class);
	  ObjectifyService.register(VendorRelation.class);
	  ObjectifyService.register(CustomerRelation.class);
	  ObjectifyService.register(Category.class);
	 
	  
	  

	  
	  ObjectifyService.register(com.slicktechnologies.shared.common.helperlayer.ConfigCategory.class);
	  ObjectifyService.register(com.slicktechnologies.shared.common.helperlayer.Type.class);
	  
	
	 
	
	
	}
	catch(Exception e)
	{
		System.out.println("sumedh");
		e.printStackTrace();
		
	}
    }
	
	/* (non-Javadoc)
	 * @see com.simplesoftwares.client.library.libservice.GenricService#save(com.simplesoftwares.client.library.appstructure.SuperModel)
	 */
	@Override
	public ReturnFromServer save(SuperModel m) 
	{
		
		if(m.getCount()==0)
	    {
	    	
			int count;
		    if(m.getCompanyId()!=null)			
			  count=ofy().load().type(m.getClass()).filter("companyId",m.getCompanyId()).count();
		    else
		    	count=ofy().load().type(m.getClass()).count();
	    	
	    	m.setCount(count+1);
	    	
	    	
	    }
	   
		
	    ofy().save().entity(m).now();
	    //Setting count
	  int  count=ofy().load().type(m.getClass()).count();
   
	   
	    ReturnFromServer server = new ReturnFromServer();
	    server.id=m.getId();
	    server.count=m.getCount();
	   return server;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.client.library.libservice.GenricService#update(com.simplesoftwares.client.library.appstructure.SuperModel)
	 */
	@Override
	public void update(SuperModel m) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.client.library.libservice.GenricService#delete(com.simplesoftwares.client.library.appstructure.SuperModel)
	 */
	@Override
	public void delete(SuperModel m) {
		ofy().delete().entity(m);
		
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.client.library.libservice.GenricService#print(java.lang.Long)
	 */
	@Override
	public void print(Long id) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.client.library.libservice.GenricService#download(java.util.ArrayList)
	 */
	@Override
	public void download(ArrayList<SuperModel> m) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.client.library.libservice.GenricService#email(java.lang.Long)
	 */
	@Override
	public void email(Long id) {
		// TODO Auto-generated method stub
		
	}

	

	
   /* (non-Javadoc)
    * @see com.simplesoftwares.client.library.libservice.GenricService#getSearchResult(com.simplesoftwares.client.library.appstructure.search.MyQuerry)
    */
   @Override
   public ArrayList<SuperModel> getSearchResult(MyQuerry quer)
   
   {
	 
	   
	   
	   ArrayList<SuperModel> list=new ArrayList<SuperModel>();
	   try{
	   ofy().clear();
	   Query<? extends SuperModel> query = null;
	   //Get the querry
	   query=ofy().load().type(quer.getQuerryObject().getClass());
	   Logger logger = Logger.getLogger("NameOfYourLogger");
	   
	   //Get the 
	   if(quer.getFilters()!=null)
		{
	      for(int i=0;i<quer.getFilters().size();i++)
			{
			      String conditionField=quer.getFilters().get(i).getQuerryString();
			     
			      Object value=quer.getFilters().get(i).geFilterValue();
			    
			      if(value instanceof Date)
			        {
			    	  
			    	  logger.log(Level.SEVERE,"Condition Field "+conditionField);
				        logger.log(Level.SEVERE,"Condition Value "+value);
				        logger.log(Level.SEVERE,"Size of Querry "+query.count());
				        GWT.log("Condition Field "+conditionField);
				        GWT.log("Condition Value "+value);
			    	  logger.log(Level.SEVERE,"Condition Value before parsed "+value.toString());
			    	  Date condDate= parseDate((Date) value);
			    	 // Very dangerous patch learn internationalization and recode
			    	 Calendar c = Calendar.getInstance(); 
			    	 c.setTime(condDate); 
			    	 c.add(Calendar.DATE, 1);
			    	 condDate = c.getTime();
			    	 condDate= parseDate((Date) condDate);
			    	 logger.log(Level.SEVERE,"Condition Value When parsed "+condDate);
			    	 logger.log(Level.SEVERE,"Condition Field When parsed "+conditionField);
			    	 query=query.filter(conditionField,condDate);
			    	}
			      else
			      {
			    	    
			           
			           logger.log(Level.SEVERE,"Condition Field "+conditionField);
				        logger.log(Level.SEVERE,"Condition Value "+value);
				        query=query.filter(conditionField,value);
				        logger.log(Level.SEVERE,"Size of Querry "+query.count());
			        
			      }
			        
			      
			       
			       
		}
	      
		}    
	      ObjectifyService.reset();
	      ofy().consistency(Consistency.STRONG);
	      logger.log(Level.SEVERE,"Size of Querry "+query.count());
	      logger.log(Level.SEVERE,"Type Of"+quer.getQuerryObject().getClass());
	      
		   ofy().clear();
			for(SuperModel i:query)
				    list.add(i);
	   }
	   catch(Exception e)
	   {
		   e.printStackTrace();
	   }
	      	
		
	return list;
   }
   
   /* (non-Javadoc)
    * @see com.simplesoftwares.client.library.libservice.GenricService#getCount(com.simplesoftwares.client.library.appstructure.SuperModel)
    */
   @Override
   public int getCount(SuperModel m)
   {
	   
	   if(m.getCount()==0)
	   {
	   int count =ofy().load().type(m.getClass()).count();
	   return count;
	   }
	   return m.getCount();
   }
   
   
   
   
   /**
    * Parses the date.
    *
    * @return the date
    */
   public static Date parseDate()
   
	{   
	   Date todayWithZeroTime=null;
	   try{
		
		DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		Date today = new Date();
		todayWithZeroTime =formatter.parse(formatter.format(today));
		Logger logger = Logger.getLogger("NameOfYourLogger");
       	logger.log(Level.SEVERE,todayWithZeroTime+"");
       	logger.log(Level.SEVERE,"SAVIAM");
	     
	}
	catch(Exception e)
	{
		e.printStackTrace();
		
	}
		
	   return todayWithZeroTime;
	}
   
   
   /**
    * Parses the date.
    *
    * @param date the date
    * @return the date
    */
   public static Date parseDate(Date date)
   
  	{   
  	   Date todayWithZeroTime=null;
  	   try{
  		
  		DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
        todayWithZeroTime =formatter.parse(formatter.format(date));
  	     
  	}
  	catch(Exception e)
  	{
  		e.printStackTrace();
  		System.out.println("NAME IS ");
  	}
  		
  	   return todayWithZeroTime;
  	}

/* (non-Javadoc)
 * @see com.simplesoftwares.client.library.libservice.GenricService#save(java.util.ArrayList)
 */
@Override
public ArrayList<ReturnFromServer> save(ArrayList<SuperModel> m) {
	
	int count=ofy().load().type(m.get(0).getClass()).count();
	ArrayList<ReturnFromServer>server=new ArrayList<ReturnFromServer>();
	for(SuperModel model:m)
	{
		ReturnFromServer temp=new ReturnFromServer();
		server.add(temp);
		temp.id=model.getId();
	
	  if(model.getCount()==0)
      {
    	
    	model.setCount(count+1);
    	temp.count=model.getCount();

    	count++;
    	;
      }
   
	}
    //Setting count
   
   ofy().save().entities(m).now();
   for(int i=0;i<m.size();i++)
   {
	  if(server.get(i).id==null)
		  server.get(i).id=m.get(i).getId();
   }
   
    
   return server;
}

@Override
public void putInMemCache(SuperModel model) {
	// TODO Auto-generated method stub
	
}


		
}





